#pragma once
#ifdef _WIN32
#ifndef ___MOD_STRING_DETAIL_HPP
#define ___MOD_STRING_DETAIL_HPP
#include <string>
#include <functional>
#include <locale>
#include "../config.hpp"
class __mod_string_detail
{
private:
	using _Ty = __mod_string_detail;
public:

	template <class _Arg, class _Result>
	struct __mod_unary_function 
	{
		using argument_type = _Arg;
		using result_type = _Result;
	};
	template <class _Arg1, class _Arg2, class _Result>
	struct __mod_binary_function 
	{
		using first_argument_type = _Arg1;
		using second_argument_type = _Arg2;
		using result_type = _Result;
	};
	template <class char_t>
	class __mod_not_space : public __mod_unary_function<bool, char_t>
	{
	public:
		__mod_not_space(std::locale const& loc) :facet_(std::use_facet<std::ctype<char_t>>(loc)) {}
		bool operator()(char_t character)
		{
			if (!(facet_.is(std::ctype_base::space, character)))
			{
				return true;
			}
			return false;
		}
	private:
		std::ctype<char_t> const& facet_;
	};
	template <class char_t, class traits_t>
	struct __mod_traits_equal : public __mod_binary_function<bool, char_t, char_t>
	{
		bool operator()(char_t c1, char_t c2)
		{
			return traits_t::eq(c1, c2);
		}
	};

	template <class char_t, class traits_t>
	class __mod_traits_iequal : public __mod_binary_function<bool, char_t, char_t>
	{
	public:
		__mod_traits_iequal(std::locale const& loc) :facet_(std::use_facet<std::ctype<char_t> >(loc)){}
		bool operator()(char_t c1, char_t c2)
		{
			return traits_t::eq(facet_.tolower(c1), facet_.tolower(c2));
		}
	private:
		std::ctype<char_t> const& facet_;
	};
	//template <class char_t, class traits_t, class allocator_t,class _Iterator>
	//static __forceinline void trim_left(const std::basic_string<char_t, traits_t, allocator_t>&  _Str, std::locale const& loc = std::locale())
	//{
	//	
	//	_Iterator it = std::find_if(_Str.begin(), _Str.end(), __mod_not_space<char_t>(loc));
	//	_Str.erase(_Str.begin(), it);
	//}
	//template <class char_t, class traits_t, class allocator_t, class _Iterator>
	//static __forceinline void trim_right(std::basic_string<char_t, traits_t, allocator_t>& _Str, std::locale const& loc = std::locale())
	//{
	//	typedef std::basic_string<char_t, traits_t, allocator_t> string_type;
	//	typedef typename string_type::reverse_iterator reverse_iterator;
	//	reverse_iterator it = std::find_if(_Str.rbegin(), _Str.rend(), __mod_not_space<char_t>(loc));
	//	_Str.erase(it.base(), _Str.end());
	//}
	//template <class char_t, class traits_t, class allocator_t, class _Iterator>
	//static __forceinline  void trim(std::basic_string<char_t, traits_t, allocator_t>& input, std::locale const& loc = std::locale())
	//{
	//	trim_left<char_t, traits_t, allocator_t, _Iterator>(input, loc);
	//	trim_right<char_t, traits_t, allocator_t, _Iterator>(input, loc);
	//}
	template <class _Elem = char>
	static __forceinline bool equal(const _Elem* _First1, const _Elem* _First2, size_t _Count) noexcept
	{

		for (; 0 < _Count; --_Count, ++_First1, ++_First2)
		{
			if (*_First1 != *_First2)
			{
				return false;
			}
		}
		return true;
	}
	template <class _Elem = char>
	static __forceinline bool iequal(const _Elem* _First1, const _Elem* _First2, size_t _Count) noexcept
	{
		for (; 0 < _Count; --_Count, ++_First1, ++_First2)
		{
			_Elem c1 = *_First1;
			_Elem c2 = *_First2;
			if (c1 != c2)
			{
				if (c1 >= (_Elem)'A' && c1 <= (_Elem)'Z')
				{
					c1 -= (_Elem)('A' - 'a');
					if (c1 != c2)
					{
						return false;
					}
				}
				else
				{
					return false;
				}
			}
		}
		return true;
	}
	template <class _Elem = char>
	static __forceinline size_t length(const _Elem* const Ptr) noexcept
	{
		_Elem* _First = (_Elem*)Ptr;
		while (*_First != _Elem())
		{
			++_First;
		}
		return (size_t)(_First - Ptr);
	}
	//template <class _Elem, class _List>
	//static std::vector<_List> split(const std::basic_string<_Elem, std::char_traits<_Elem>, std::allocator<_Elem>>& s, const _Elem* const delim)
	//{
	//	std::vector<_List> result;
	//	size_t lastPos = s.find_first_not_of(delim, 0);
	//	size_t pos = s.find(delim, lastPos);
	//	while (lastPos != std::basic_string<_Elem, std::char_traits<_Elem>, std::allocator<_Elem>>::npos) 
	//	{
	//		result.emplace_back(s.substr(lastPos, pos - lastPos));
	//		lastPos = s.find_first_not_of(delim, pos);
	//		pos = s.find(delim, lastPos);
	//	}
	//	return result;
	//}
	template <class _Elem, class _List>
	static std::vector<_List> split(const std::basic_string<_Elem, std::char_traits<_Elem>, std::allocator<_Elem>>& src, const _Elem* const pattern)
	{
		std::vector<_List> elems;
		size_t pos = 0;
		size_t len = _Ty::length(src.data());
		if (len == 0)
		{
			return elems;
		}
		size_t delim_len = _Ty::length(pattern);
		if (delim_len == 0)
		{
			return elems;
		}
		while (pos < len)
		{
			size_t find_pos = src.find(pattern, pos);
			if (find_pos < 0 || find_pos>len)
			{
				elems.emplace_back(src.substr(pos, len - pos));
				break;
			}
			elems.emplace_back(src.substr(pos, find_pos - pos));
			pos = find_pos + delim_len;
		}
		return elems;
	}
private:

};
__MOD_BEGIN

__MOD_END
#endif
#endif // WIN32